home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 7 / PC World Interactive 7.iso / program / cprog.EXE / ICONBMP.ZIP / ICO2BMP.C next >
C/C++ Source or Header  |  1996-01-08  |  8KB  |  309 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                            */
  3. /* Ico2bmp - Small utility program, which reads a icon file (.ico), extracts*/
  4. /* the color part of the icon, and generates a bitmap file (.bmp).            */
  5. /*                                                                            */
  6. /* Author: Niels Erik Holm, ICL DATA A/S, Copenhagen Denmark, neh@rci.dk    */
  7. /* No copyrights apply, no Warranty                                            */
  8. /*                                                                            */
  9. /*--------------------------------------------------------------------------*/
  10.  
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <process.h>
  15. #include <dos.h>
  16.  
  17. char *    Version = "Ico2bmp v1.0 - Extracts color bitmap from icon file - Author: neh@rci.dk";
  18.  
  19. typedef    struct {
  20.     WORD    icoReserved;        /* Reserved, must be set to 0    */
  21.     WORD    icoResourceType;    /* Resource type, 1 for icon resources */
  22.     WORD    icoResourceCount;    /* Number of images in the file */
  23. }    IconFileHeader;
  24.  
  25. typedef    struct {
  26.     BYTE    Width;                /* Width in pixels */
  27.     BYTE    Height;                /* Height in pixels */
  28.     BYTE    ColorCount;            /* Number of colors */
  29.     BYTE    Reserved1;
  30.     WORD    Reserved2;
  31.     WORD    Reserved3;
  32.     DWORD    icoDIBSize;            /* Size in bytes of the pixel array */
  33.     DWORD    icoDIBOffset;        /* Offset in bytes from beginning of file */
  34.                                 /* to pixel array. */
  35. }    IconRscDir;
  36.  
  37. typedef    struct {
  38.     IconFileHeader    IHead;        /* Icon file header */
  39.     IconRscDir        IDir;        /* Icon resource directory */
  40.     BYTE            IBits[1000];
  41. }    IconFile;
  42.  
  43. BITMAPFILEHEADER    bmFH;
  44. BITMAPINFOHEADER    bmIH;
  45. RGBQUAD                bmCol[16];
  46.  
  47. unsigned char        Idata[1000];
  48. unsigned char        Odata[1000];
  49.  
  50. int        opterr = 1;
  51. int        optind = 1;
  52. int        optopt;
  53. char *    optarg;
  54.  
  55. struct    find_t    fb;
  56. int        MoreFiles;
  57.  
  58. static int getopt(int,char **,char *);
  59. static int  ProcessFile(char *,char *);
  60. static void ManipulateBits(BYTE *,BYTE *,int);
  61. static void usage(void);
  62.  
  63. main(argc,argv)
  64. int argc;
  65. char *argv[];
  66. {
  67.     int        opt,attr;
  68.     char *    Fptr;
  69.     char    InFileSpec[64];
  70.     char    FirstName[64];
  71.     char    InName[64];
  72.     char    OutName[64];
  73.  
  74.     InFileSpec[0] = 0;
  75.     attr = 0;
  76.  
  77.     while ((opt = getopt(argc,argv,"hi:")) != -1)
  78.         switch (opt) {
  79.             case 'h':
  80.                 usage();
  81.                 exit(1);
  82.                 break;
  83.             case 'i':
  84.                 strcpy(InFileSpec,optarg);
  85.                 break;
  86.         }
  87.  
  88.     if (InFileSpec[0] == 0) {
  89.         usage();
  90.         exit(1);
  91.     }
  92.  
  93.     if ((Fptr = strchr(InFileSpec,'.')) == NULL)
  94.         strcat(InFileSpec,".ico");
  95.  
  96.     MoreFiles = (_dos_findfirst(InFileSpec,attr,&fb) == 0);
  97.     if (!MoreFiles) {
  98.         fprintf (stderr,"No files matching %s\n",InFileSpec);
  99.         exit(1);
  100.     }
  101.  
  102.     strcpy(FirstName,fb.name);
  103.  
  104.     while (MoreFiles) {
  105.  
  106.         strcpy(InName,fb.name);
  107.         strcpy(OutName,InName);
  108.         Fptr = strchr(OutName,'.');
  109.         strcpy(Fptr,".bmp");
  110.  
  111.         (void) ProcessFile(InName,OutName);
  112.  
  113.         MoreFiles = ((_dos_findnext(&fb)==0) && (strcmp(FirstName,fb.name)!=0));
  114.     }
  115. }
  116.  
  117. static int ProcessFile(char * InFileName,char * OutFileName)
  118. {
  119.     FILE *        Ifile;
  120.     FILE *        Ofile;
  121.     IconRscDir*    pIRD;
  122.     BITMAPINFOHEADER * pBMIH;
  123.     RGBQUAD *    pRGB;
  124.     BYTE *        pColorData;
  125.     BYTE *        pMonoData;
  126.     int            i,j,Ino,Cno,DataNo,ColorTabSize,BitMapSize,Pixels,BitsPerPixel;
  127.     char *        Iptr;
  128.     unsigned char *        Bptr;
  129.  
  130.  
  131.     if ((Ifile = fopen(InFileName,"rb")) == NULL) {
  132.         fprintf (stderr,"Error opening input file %s\n",InFileName);
  133.         return(0);
  134.     }
  135.     fread (Idata,1,sizeof(Idata),Ifile);
  136.     fclose(Ifile);
  137.  
  138.     if ((Ofile = fopen(OutFileName,"wb")) == NULL) {
  139.         fprintf (stderr,"Error opening output file %s\n",OutFileName);
  140.         return(0);
  141.     }
  142.  
  143.     fprintf (stdout,"Processing %s -> %s",InFileName,OutFileName);
  144.  
  145.     Iptr = Idata;
  146.  
  147.     if (((IconFileHeader *)Iptr)->icoReserved != 0) {
  148.         fprintf (stderr,"\nSorry! Invalid icon file.\n");
  149.         return(0);
  150.     }
  151.  
  152.     Ino = ((IconFileHeader *)Iptr)->icoResourceCount;
  153.     if (Ino != 1) {
  154.         fprintf (stderr,"\nSorry! Ico2bmp can only handle icon file with one icons.\n");
  155.         return(0);
  156.     }
  157.  
  158.     Iptr += sizeof(IconFileHeader);
  159.     pIRD = (IconRscDir *)Iptr;
  160.     pBMIH= (BITMAPINFOHEADER *)(Idata + pIRD->icoDIBOffset);
  161.     pRGB = (RGBQUAD *)((BYTE *)pBMIH+sizeof(BITMAPINFOHEADER));
  162.     ColorTabSize = pIRD->ColorCount*sizeof(RGBQUAD);
  163.     pColorData = (BYTE *)((BYTE *)pRGB+ColorTabSize);
  164.     BitsPerPixel = pBMIH->biBitCount;
  165.     Pixels = pIRD->Width*pIRD->Height*BitsPerPixel;
  166.     BitMapSize = Pixels/8;
  167.     pMonoData = (BYTE *)(pColorData + BitMapSize);
  168.  
  169.     Cno=pBMIH->biBitCount;
  170.     if (Cno==1)
  171.         Cno=2;
  172.     else if (Cno==4)
  173.         Cno=16;
  174.     else if (Cno==8)
  175.         Cno=256;
  176.     else if (Cno==24)
  177.         Cno=0;
  178.  
  179.     if (Cno != 16) {
  180.         fprintf (stderr,"\nSorry! Ico2bmp can only handle 16 color icons\n");
  181.         return(0);
  182.     }
  183.  
  184.     bmFH.bfType = 'B' | 'M'<<8;
  185.     bmFH.bfSize = sizeof(bmFH)+sizeof(bmIH)+ColorTabSize+BitMapSize;
  186.  
  187.     bmFH.bfOffBits = sizeof(bmFH)+sizeof(bmIH)+ColorTabSize;
  188.  
  189.     bmIH.biSize                = pBMIH->biSize;
  190.     bmIH.biWidth            = pBMIH->biWidth;
  191.     bmIH.biHeight            = pBMIH->biHeight/2;
  192.     bmIH.biPlanes            = pBMIH->biPlanes;
  193.     bmIH.biBitCount            = pBMIH->biBitCount;
  194.     bmIH.biCompression        = pBMIH->biCompression;
  195.     bmIH.biSizeImage        = BitMapSize;
  196.     bmIH.biXPelsPerMeter    = pBMIH->biXPelsPerMeter;
  197.     bmIH.biYPelsPerMeter    = pBMIH->biYPelsPerMeter;
  198.     bmIH.biClrUsed            = pBMIH->biClrUsed;
  199.     bmIH.biClrImportant        = Cno;
  200.  
  201.     for (i=0;i<Cno;i++)
  202.         bmCol[i] = *((RGBQUAD*)((BYTE*)pRGB + i*sizeof(RGBQUAD)));
  203.  
  204.     ManipulateBits(pColorData,pMonoData,Pixels);
  205.  
  206.     memcpy(Odata,pColorData,BitMapSize);
  207.  
  208.     fwrite(&bmFH,sizeof(bmFH),1,Ofile);
  209.     fwrite(&bmIH,sizeof(bmIH),1,Ofile);
  210.     fwrite(&bmCol[0],ColorTabSize,1,Ofile);
  211.     fwrite(&Odata[0],BitMapSize,1,Ofile);
  212.  
  213.     fclose(Ofile);
  214.  
  215.     fprintf (stdout,"\n");
  216.  
  217.     return(1);
  218. }
  219.  
  220. static void ManipulateBits(BYTE * pColorData,BYTE * pMonoData,int pixels)
  221. /* Works only on 16 color bitmaps */
  222. {
  223.     register int i,MonoBits,XorMask,j;
  224.     register BYTE * pMD;
  225.  
  226.     pMD = pMonoData;
  227.     MonoBits = *pMD;
  228.     j=0;
  229.  
  230.     for (i=0;i<pixels/2;i++) {
  231.         if (MonoBits & 0x80)
  232.             *(pColorData+i) |= 0xF0;
  233.         MonoBits <<= 1;
  234.         j++;
  235.         if (MonoBits & 0x80)
  236.             *(pColorData+i) |= 0x0F;
  237.         MonoBits <<= 1;
  238.         j++;
  239.         if (j==8) {
  240.             ++pMD;
  241.             MonoBits = *pMD;
  242.             j=0;
  243.         }
  244.     }
  245. }
  246.  
  247. static void usage()
  248. {
  249.     fprintf (stdout,"%s\n",Version);
  250.     fprintf (stdout,"Usage: ico2bmp -i <inputfile> [-h]\n");
  251.     fprintf (stdout,"\n");
  252.     fprintf (stdout," -h:  Display this help\n");
  253.     fprintf (stdout," -i:  Name of input file. If no extension is specified .ico is used.\n");
  254.     fprintf (stdout,"      Wildcards are allowed. Ex. -i *.ico\n");
  255. }
  256.  
  257. #define    index    strchr
  258.  
  259. #define ERR(s, c)    if(opterr){\
  260.     extern int write();\
  261.     char errbuf[2];\
  262.     errbuf[0] = c; errbuf[1] = '\n';\
  263.     (void) fprintf(stderr, argv[0], (unsigned)strlen(argv[0]));\
  264.     (void) fprintf(stderr, s, (unsigned)strlen(s));\
  265.     (void) fprintf(stderr, errbuf, 2);}
  266.  
  267. static int getopt(int argc, char ** argv, char * opts)
  268. {
  269.     static int sp = 1;
  270.     register int c;
  271.     register char *cp;
  272.  
  273.     if(sp == 1)
  274.         if(optind >= argc ||
  275.            argv[optind][0] != '-' || argv[optind][1] == '\0')
  276.             return(-1);
  277.         else if(strcmp(argv[optind], "--") == 0) {
  278.             optind++;
  279.             return(-1);
  280.         }
  281.     optopt = c = argv[optind][sp];
  282.     if(c == ':' || (cp=index(opts, c)) == 0) {
  283.         ERR(": illegal option -- ", c);
  284.         if(argv[optind][++sp] == '\0') {
  285.             optind++;
  286.             sp = 1;
  287.         }
  288.         return('?');
  289.     }
  290.     if(*++cp == ':') {
  291.         if(argv[optind][sp+1] != '\0')
  292.             optarg = &argv[optind++][sp+1];
  293.         else if(++optind >= argc) {
  294.             ERR(": option requires an argument -- ", c);
  295.             sp = 1;
  296.             return('?');
  297.         } else
  298.             optarg = argv[optind++];
  299.         sp = 1;
  300.     } else {
  301.         if(argv[optind][++sp] == '\0') {
  302.             sp = 1;
  303.             optind++;
  304.         }
  305.         optarg = 0;
  306.     }
  307.     return(c);
  308. }
  309.